package cn.cuilan.config;

import cn.cuilan.service.SysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

/**
 * web安全Java配置类
 *
 * @author zhang.yan
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final static Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);

    private final SysUserService sysUserService;

    private final PasswordEncoder passwordEncoder;

    @Autowired
    public WebSecurityConfig(SysUserService sysUserService, PasswordEncoder passwordEncoder) {
        this.sysUserService = sysUserService;
        this.passwordEncoder = passwordEncoder;
    }

    @Bean
    public LoginSuccessHandler loginSuccessHandler() {
        return new LoginSuccessHandler();
    }

    @Bean
    public LoginFailureHandler loginFailureHandler() {
        return new LoginFailureHandler();
    }

    @Bean
    public LogoutSuccessHandler logoutSuccessHandler() {
        return new LogoutSuccessHandler();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/").permitAll() // 可以访问
                .antMatchers("/admin/**").authenticated() // 该前缀的接口都需要验证
                .and()
                .formLogin().loginProcessingUrl("/admin/login")
                .successForwardUrl("/") // 登录成功后跳转
                .successHandler(loginSuccessHandler()) // 登录成功后的处理
                .failureHandler(loginFailureHandler()) // 登录失败后的处理
                .permitAll()
                .and()
                .rememberMe() // cookie
                .and()
                .logout().logoutUrl("/admin/logout")
                .logoutSuccessHandler(logoutSuccessHandler()) // 登出成功后的处理
                .permitAll();

        //session管理
        //session失效后跳转
        http.sessionManagement().invalidSessionUrl("/");
        //只允许一个用户登录,如果同一个账户两次登录,那么第一个账户将被踢下线,跳转到登录页面
        http.sessionManagement().maximumSessions(1).expiredUrl("/login");

        // 关闭 Http Base 认证
        http.httpBasic().disable();
        // 关闭 CSRF 跨站请求伪造
        http.csrf().disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(sysUserService).passwordEncoder(passwordEncoder);
    }

}
